package com.baidu.mapapi.demo.ui.gps;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKAddrInfo;
import com.baidu.mapapi.MKBusLineResult;
import com.baidu.mapapi.MKDrivingRouteResult;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MKPoiInfo;
import com.baidu.mapapi.MKPoiResult;
import com.baidu.mapapi.MKSearch;
import com.baidu.mapapi.MKSearchListener;
import com.baidu.mapapi.MKSuggestionResult;
import com.baidu.mapapi.MKTransitRouteResult;
import com.baidu.mapapi.MKWalkingRouteResult;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.OverlayItem;
import com.baidu.mapapi.Projection;
import com.baidu.mapapi.demo.FrameParam;
import com.baidu.mapapi.demo.BMapHelp;
import com.baidu.mapapi.demo.R;

/**
 * 
 * @author lilin
 * @date 2012-11-23 下午1:43:34
 * @annotation 根据GPS定位点，范围查询
 */
public class BMap_GPS_ExtentClick extends MapActivity {
	public static MapView mapView;

	public static View popView;
	private TextView showTextView;
	private MKSearch mkSearch;
	List<MKPoiInfo> poiList = new ArrayList<MKPoiInfo>();// 查询到的点的列表

	private LocationListener mLocationListener = null;
	private MKLocationManager locationManager;

	private double gx;
	private double gy;
	private GeoPoint gpsGeoPoint;

	private FrameParam app;

	private Boolean isGPS = true;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.bmap_markmap);
		setTitle("定位签到");

		initUI();

		// 初始化搜索
		mkSearch = new MKSearch();
		mkSearch.init(app.mBMapManager, new MySearch());

		mLocationListener = new LocationListener() {

			@Override
			public void onLocationChanged(Location location) {
				if (location != null) {

					if (isGPS == true) {

						gx = location.getLatitude();
						gy = location.getLongitude();
						gpsGeoPoint = BMapHelp.gpsToGeoPoint(gx, gy);

						// 测试点
						gpsGeoPoint = new GeoPoint((int) (39.915 * 1E6),
								(int) (116.404 * 1E6));
						mapView.getController().animateTo(gpsGeoPoint);// 移到已该点为中心

						mkSearch.reverseGeocode(gpsGeoPoint);// 反地址解析

						isGPS = false;
					}
				}

			}

		};
		BMapHelp.zoomTOBig(mapView);
	}

	private void initUI() {
		app = (FrameParam) this.getApplication();
		if (app.mBMapManager == null) {
			app.mBMapManager = new BMapManager(getApplication());
			app.mBMapManager.init(app.mapKey, new FrameParam.MyGeneralListener());
		}
		locationManager = app.mBMapManager.getLocationManager();
		app.mBMapManager.start();

		this.initMapActivity(app.mBMapManager);// 初始化

		mapView = (MapView) findViewById(R.id.bmapView);

		mapView.setBuiltInZoomControls(true);// 允许缩放操作
		mapView.getController().setZoom(18);// 设置缩放级别为3-18
		mapView.setDoubleClickZooming(true);// 允许双击放大
		mapView.setDrawOverlayWhenZooming(true);// 设置在缩放动画过程中也显示overlay,默认为不绘制

		// 初始化气泡
		popView = getLayoutInflater().inflate(R.layout.bmap_popview, null);
		mapView.addView(popView, new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT, null,
				MapView.LayoutParams.TOP));
		popView.setVisibility(View.GONE);

		showTextView = (TextView) popView.findViewById(R.id.title);
		showTextView.setText("正在搜索中...");
		showTextView.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				showPOIDetail();
			}
		});

	}

	/**
	 * @author lilin
	 * @date 2012-11-27 下午4:21:48
	 * @annotation 显示POI详情
	 */
	protected void showPOIDetail() {
		for (int i = 0; i < poiList.size(); i++) {
			if (poiList.get(i).name.equals(showTextView.getText().toString()
					.trim())) {
				BMapHelp.showPoiByDialog(BMap_GPS_ExtentClick.this,
						poiList.get(i));
			}
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, 0, 0, "中心点坐标");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case 0:
			addMarkOverlay(this, mapView.getMapCenter(),
					R.drawable.bmap_point_green);
			break;

		default:
			break;
		}
		return super.onMenuItemSelected(featureId, item);
	}

	public void addMarkOverlay(Context con, GeoPoint geoPoint, int id) {

		// mapView.getController().animateTo(geoPoint);// 移到已该点为中心
		mapView.getOverlays().clear();// 添加前清空所有图层
		BMap_MarkOverlay markOverlay = new BMap_MarkOverlay(con, geoPoint,
				BMapHelp.setMarkImg(this, id));
		mapView.getOverlays().add(markOverlay); // 添加ItemizedOverlay实例到mMapView
		mapView.invalidate();

	}

	public void addMarkOverlay(Context con, List<GeoPoint> plist, int id,
			List<String> title) {
		// BMapHelp.printPoint("第一个POI点", plist.get(0));
		// mapView.getController().animateTo(plist.get(0));// 移到已该点为中心
		mapView.getOverlays().clear();// 添加前清空所有图层
		BMap_MarkOverlay markOverlay = new BMap_MarkOverlay(con, plist,
				BMapHelp.setMarkImg(con, id), title);
		mapView.getOverlays().add(markOverlay); // 添加ItemizedOverlay实例到mMapView
		mapView.invalidate();
	}

	@Override
	protected void onPause() {
		FrameParam app = (FrameParam) this.getApplication();
		if (app.mBMapManager != null) {
			locationManager.removeUpdates(mLocationListener);
			app.mBMapManager.stop();
		}
		super.onPause();
	}

	@Override
	protected void onResume() {
		FrameParam app = (FrameParam) this.getApplication();

		locationManager.requestLocationUpdates(mLocationListener);

		app.mBMapManager.start();
		super.onResume();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	protected void onDestroy() {

		FrameParam app = (FrameParam) this.getApplication();
		if (app.mBMapManager != null) {
			app.mBMapManager.destroy();
			app.mBMapManager = null;
		}
		super.onDestroy();
	}

	// 标记图层
	class BMap_MarkOverlay extends ItemizedOverlay<OverlayItem> implements
			OnGestureListener {

		public List<OverlayItem> itemList = new ArrayList<OverlayItem>();

		private Drawable img;
		public Context con;

		private GestureDetector gestureScanner = new GestureDetector(this);

		BMap_MarkOverlay(Context context, GeoPoint mGeoPoint, Drawable marker) {
			super(boundCenterBottom(marker));
			itemList = new ArrayList<OverlayItem>();
			this.img = marker;
			this.con = context;

			itemList.add(new OverlayItem(mGeoPoint, "", ""));

			populate(); // 刷新地图
		}

		BMap_MarkOverlay(Context context, List<GeoPoint> pList,
				Drawable marker, List<String> title) {
			super(boundCenterBottom(marker));
			itemList = new ArrayList<OverlayItem>();
			this.img = marker;
			this.con = context;

			for (int i = 0; i < pList.size(); i++) {
				itemList.add(new OverlayItem(pList.get(i), "", title.get(i)));
			}

			populate(); // 刷新地图
		}

		public void updateOverlay() {
			populate();
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {

			Projection projection = mapView.getProjection();// Projection接口用于屏幕像素坐标和经纬度坐标之间的变换

			for (int index = size() - 1; index >= 0; index--) { // 遍历mGeoList
				OverlayItem overLayItem = getItem(index); // 得到给定索引的item

				String title = overLayItem.getTitle();

				Point point = projection.toPixels(overLayItem.getPoint(), null);// 把经纬度变换到相对于MapView左上角的屏幕像素坐标

				// 可在此处添加您的绘制代码
				Paint paint = new Paint();
				paint.setColor(Color.BLUE);
				paint.setTextSize(15);
				canvas.drawText(title, point.x - 50, point.y, paint); // 绘制文本

				paint.setAntiAlias(true);
				paint.setColor(Color.BLUE);
				paint.setStyle(Paint.Style.STROKE);// 设置样式
				paint.setStrokeWidth(2);// 设置粗细

				canvas.drawCircle(10, 20, 10, paint);
			}

			super.draw(canvas, mapView, shadow);
			boundCenterBottom(img);// 调整一个drawable边界，使得（0，0）是这个drawable底部最后一行中心的一个像素
		}

		@Override
		protected OverlayItem createItem(int i) {
			return itemList.get(i);
		}

		@Override
		public int size() {
			return itemList.size();
		}

		@Override
		protected boolean onTap(int i) {// 处理当点击事件
			setFocus(itemList.get(i));// 获得焦点
			GeoPoint geoPoint = itemList.get(i).getPoint(); // 更新气泡位置,并使之显示
			LayoutParams params = new MapView.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
					geoPoint, MapView.LayoutParams.BOTTOM_CENTER);
			mapView.updateViewLayout(popView, params);
			// MapView.LayoutParams params = (MapView.LayoutParams) popView
			// .getLayoutParams();
			// params.point = geoPoint;// 设置显示的位置
			mapView.updateViewLayout(popView, params);
			popView.setVisibility(View.VISIBLE);
			showTextView.setText(itemList.get(i).getSnippet());
			// Toast.makeText(this.con, itemList.get(i).getSnippet(),
			// 5000).show();
			return true;
		}

		@Override
		public boolean onTap(GeoPoint arg0, MapView arg1) {
			popView.setVisibility(View.GONE);// 消去弹出的气泡
			return super.onTap(arg0, arg1);
		}

		@Override
		public boolean onDown(MotionEvent arg0) {
			return false;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {

			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {
			longPressEvent(e);
		}

		@Override
		public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
				float arg3) {
			return false;
		}

		@Override
		public void onShowPress(MotionEvent arg0) {

		}

		@Override
		public boolean onSingleTapUp(MotionEvent arg0) {
			return false;
		}

		// ***必不可少，否则触摸事件无效
		@Override
		public boolean onTouchEvent(MotionEvent arg0, MapView arg1) {
			return gestureScanner.onTouchEvent(arg0);
		}

	}

	/**
	 * 
	 * @author lilin
	 * @date 2012-11-22 下午4:46:03
	 * @annotation 搜索类（内部类）
	 */
	class MySearch implements MKSearchListener {
		// 反地址查询结果
		@Override
		public void onGetAddrResult(MKAddrInfo arg0, int arg1) {

			if (arg1 == 100) {
				showTextView.setText("地址正确，暂无法查询");
				return;
			}
			if (arg0 == null) {
				showTextView.setText("查不到此地信息");
				return;
			}

			if (arg0 != null) {
				showAddrResult(arg0);
			}

		}

		@Override
		public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {

		}

		@Override
		public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {

		}

		// 按范围查询结果
		@Override
		public void onGetPoiResult(MKPoiResult res, int type, int error) {

			if (error != 0 || res == null) { // 错误号可参考MKEvent中的定义
				// 结果为空
				return;
			}
			showPOIResult(res);

		}

		@Override
		public void onGetRGCShareUrlResult(String arg0, int arg1) {

		}

		@Override
		public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {

		}

		@Override
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {

		}

		@Override
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {

		}

	}

	private String cityName = "";

	private int extent = 500;

	/**
	 * @author lilin
	 * @date 2012-11-26 上午9:26:37
	 * @annotation 显示反地址查询的结果
	 */
	public void showAddrResult(MKAddrInfo arg0) {
		BMapHelp.showMKAddrInfo(arg0);
		if (arg0.poiList.size() > 0) {
			cityName = arg0.poiList.get(0).city;
		}
		Log.i(app.tag, "cityName=" + cityName);
		if (!TextUtils.isEmpty(cityName)) {
			mkSearch.poiSearchNearBy(cityName, gpsGeoPoint, extent);// 根据点进行范围查询
			mapView.invalidate();// 刷新
		} else {
			Toast.makeText(this, "城市名为空，无法查询！", 5000).show();
		}

		// if (arg0.type == MKAddrInfo.MK_REVERSEGEOCODE) {//
		// 地址周边Poi信息，只有在type为MK_REVERSEGEOCODE时才有效
		//
		// if (arg0.poiList != null && arg0.poiList.size() > 0) {
		// poiList.clear();
		// poiList = arg0.poiList;
		// Toast.makeText(BMap_GPS_Extent.this,
		// "地址周边有" + arg0.poiList.size() + "个Poi", 5000).show();
		// // BMapHelp.showPoiByDialog(BMap_GPS.this,
		// // arg0.poiList);//显示点的详情
		//
		// List<GeoPoint> pList = new ArrayList<GeoPoint>();
		// List<String> titleList = new ArrayList<String>();
		// for (int i = 0; i < poiList.size(); i++) {
		// pList.add(poiList.get(i).pt);
		// titleList.add(poiList.get(i).name);
		// }
		// // 在地图上显示POI标志点
		// addMarkOverlay(BMap_GPS_Extent.this, pList,
		// R.drawable.bmap_point_green, titleList);
		// }
		//
		// }

	}

	/**
	 * @author lilin
	 * @date 2012-11-26 上午9:26:37
	 * @annotation 显示按范围查询的结果
	 */
	public void showPOIResult(MKPoiResult poiResult) {

		int curNum = poiResult.getCurrentNumPois();
		if (curNum > 0) {
			Toast.makeText(this, curNum + "个", 5000).show();
			poiList.clear();
			List<GeoPoint> pList = new ArrayList<GeoPoint>();
			List<String> titleList = new ArrayList<String>();
			for (int i = 0; i < curNum; i++) {
				// BMapHelp.showMKPoiInfo(poiResult.getPoi(i));
				
				poiResult.getPoi(i).city = cityName;// 按范围查询到的city为空，所以这边我赋给它一个值
				pList.add(poiResult.getPoi(i).pt);
				titleList.add(poiResult.getPoi(i).name);
				poiList.add(poiResult.getPoi(i));
			}
			// 在地图上显示POI标志点
			addMarkOverlay(BMap_GPS_ExtentClick.this, pList,
					R.drawable.bmap_point_red, titleList);
		}
	}

	private boolean isLongPress = false;

	/**
	 * @author lilin
	 * @date 2012-11-22 下午4:48:51
	 * @annotation 长按事件
	 */
	public void longPressEvent(MotionEvent e) {
		if (isLongPress) {
			float x = e.getX();
			float y = e.getY();

			GeoPoint point = mapView.getProjection().fromPixels((int) x,
					(int) y);// 像素点转换成坐标点
			addMarkOverlay(this, point, R.drawable.bmap_point_red);// 添加标注

			// 根据地理坐标点获取地址信息 异步函数，返回结果在MKSearchListener里的onGetAddrResult方法通知
			mkSearch.reverseGeocode(point);

			mapView.invalidate();// 刷新

			MapView.LayoutParams layoutParams = (MapView.LayoutParams) popView
					.getLayoutParams();
			layoutParams.point = point;// 设置显示的位置
			mapView.updateViewLayout(popView, layoutParams);
		}

	}
}
